# -*- coding: utf-8 -*-
"""
本脚本演示如何使用 GitHub API 搜索热门项目并保存到 CSV 文件。
步骤：
1. 配置 GitHub API 访问令牌与请求头
2. 定义查询参数（例如 topic + stars）
3. 分页请求 GitHub API 获取仓库数据
4. 将结果写入 CSV 文件
"""

import os                       # 用于读取环境变量
import requests                 # 用于发送 HTTP 请求
import csv                      # 用于写入 CSV 文件
from datetime import datetime   # 用于时间戳或扩展功能
from dotenv import load_dotenv  # 用于从 .env 文件读取环境变量
from parse_config import YamlConfigReader

# === [1] GitHub API 基础配置 ===
load_dotenv()  # 自动读取项目根目录下的 .env 文件

# 通过环境变量读取 GitHub 访问令牌，避免硬编码泄露风险
ACCESS_TOKEN = os.getenv("GITHUB_ACCESS_TOKEN")
if not ACCESS_TOKEN:
    raise ValueError("请在 .env 文件中设置 GITHUB_ACCESS_TOKEN")

# GitHub API 统一的请求头（包含认证信息与返回格式）
HEADERS = {
    "Authorization": f"Bearer {ACCESS_TOKEN}",
    "Accept": "application/vnd.github+json"
}

# GitHub 搜索 API 基础 URL
GITHUB_API_URL = "https://api.github.com/search/repositories"

# === [2] 查询主题与参数 ===
args = YamlConfigReader("./config.yaml")
topic        = args.get("topic")  # 默认搜索 “AI” 主题
per_page     = args.get("per_page")  # GitHub API 每页最大返回数
max_pages    = args.get("max_pages")   # 超过多少页后停止搜索

# 查询参数配置：搜索指定主题，stars >= 1000，按星数降序排列
query_params = {
    "q": f"topic:{topic} stars:>=1000",
    "sort": "stars",
    "order": "desc",
    "per_page": per_page  # GitHub API 每页最大返回数
}

# === [3] CSV 文件配置 ===
# 输出文件名：包含主题，方便区分
CSV_FILENAME = f"github_{topic}_repos_with_desc.csv"
# CSV 表头字段
CSV_HEADERS = ["name", "url", "language", "stars", "description", "updated_at"]

# === [4] 定义函数：获取 GitHub 仓库数据 ===
def fetch_repositories():
    """
    从 GitHub API 分页获取仓库数据
    - 最多获取前 1000 条（10 页 * 每页 100 条）
    - 当返回结果不足一页时提前结束
    """
    max_pages = 10   # GitHub 限制最大 1000 条
    repos = []       # 存储所有仓库数据
    
    for page in range(1, max_pages + 1):
        # 构造带分页参数的 URL
        url = f"{GITHUB_API_URL}?page={page}"
        response = requests.get(url, headers=HEADERS, params=query_params)
        
        # 错误处理：如果返回码不是 200，停止请求
        if response.status_code != 200:
            print(f"请求失败：HTTP {response.status_code}")
            print("提示：可能是速率限制（Rate Limit）或 Token 无效。")
            break
        
        # 将返回的 JSON 转换为 Python 字典
        data = response.json()
        
        # 将本页的仓库数据加入列表
        repos.extend(data.get("items", []))
        
        # 提前终止条件：若不足 100 条说明到末尾了
        if len(data.get("items", [])) < query_params["per_page"]:
            break
    
    return repos

# === [5] 定义函数：保存结果到 CSV 文件 ===
def save_to_csv(repos, output_file):
    """
    将仓库数据写入 CSV 文件
    - 自动处理 description 为空的情况
    - 自动处理 language 为空的情况
    """
    with open(output_file, "w", newline="", encoding="utf-8", errors="ignore") as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames=CSV_HEADERS)
        writer.writeheader()  # 写入表头
        
        for repo in repos:
            # 如果 description 为空，则填充“未填写”
            description = repo["description"].strip() if repo["description"] else "未填写"
            
            writer.writerow({
                "name": repo["name"],
                "url": repo["html_url"],
                "language": repo["language"] if repo["language"] else "未标注",
                "stars": repo["stargazers_count"],
                "description": description,
                "updated_at": repo["updated_at"]
            })

# === [6] 主程序入口 ===
if __name__ == "__main__":
    # 调用 API 获取数据
    repositories = fetch_repositories()
    
    # 保存数据到 CSV
    save_to_csv(repositories, CSV_FILENAME)
    
    # 打印执行结果
    print(f"成功导出 {len(repositories)} 条数据至 {CSV_FILENAME}")
